//--------------------------------------------------------------------------
// 
//  Copyright (c) Chili Software.  All rights reserved. 
// 
//  File: SqlTransactionBase.cs
//
//  Description: Provides a base transaction object for SQL storages.
// 
//--------------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.Common;

namespace Chili.Opf3.Storages
{
	/// <summary>
	/// This class provides a general transaction object for storages that inherit from
	/// <see cref="SqlStorageBase">SqlStorageBase</see>. It adds the references to ADO.NET
	/// to the transaction objects, since it encapsulates an ADO.NET transaction internally.
	/// </summary>
	public abstract class SqlTransactionBase : Transaction
	{
		private IDbTransaction _transaction;

		/// <summary>
		/// Creates a new instance of the <see cref="SqlTransactionBase">SqlTransactionBase Class</see>.
		/// </summary>
		/// <param name="transaction">Specifies the current transaction on the storage.</param>
		protected SqlTransactionBase(IDbTransaction transaction) 
			: base()
		{
			if (transaction == null)
				throw new ArgumentNullException("transaction");

			_transaction = transaction;
		}

		/// <summary>
		/// Returns the IDbTransaction of the current transaction or null if no longer active.
		/// </summary>
		public IDbTransaction InnerTransaction
		{
			get
			{
				if (this.Active)
					return _transaction;
				return null;
			}
		}

		#region Overridden Members

		/// <summary>
		/// Returns whether the transaction is active.
		/// </summary>
		public override bool Active
		{
			get { return (_transaction != null); }
		}

		/// <summary>
		/// Commits the current transaction.
		/// </summary>
		public override void Commit()
		{
			// Only commit if the nesting level is zero. If nested transaction don't commit!
			if (this.Active)
			{
				IDbConnection connection = _transaction.Connection;
				_transaction.Commit();
				_transaction.Dispose();
				_transaction = null;

				if (connection != null)
				{
					// Close the associated connection.
					connection.Close();
				}
			}

			// Invoke the base method.
			base.Commit();
		}

		/// <summary>
		/// Rolls the current transaction back.
		/// </summary>
		public override void Rollback()
		{
			if (this.Active)
			{
				IDbConnection connection = _transaction.Connection;
				_transaction.Rollback();
				_transaction.Dispose();
				_transaction = null;

				if (connection != null)
				{
					// Close the associated connection.
					connection.Close();
				}
			}

			// Invoke the base method.
			base.Rollback();
		}

		#endregion
	}
}
